import os
import uuid
from fastapi import Cookie, Depends, FastAPI, HTTPException, Request, Response, Security, UploadFile
from fastapi.security import SecurityScopes

app = FastAPI()


# SecurityScopes 获取功能函数要求的权限范围
def print_scopes(security_scopes: SecurityScopes):
    print(security_scopes.scopes)  # ['admin', 'user']


@app.get("/group/admin", dependencies=[Security(print_scopes, scopes=["admin"])])
async def admin_only():
    pass


@app.get("/group/user", dependencies=[Security(print_scopes, scopes=["user"])])
async def user_only():
    pass


@app.get("/group/admin_or_user", dependencies=[Security(print_scopes, scopes=["admin", "user"])])
async def admin_or_user():
    pass


# 根据cookie获取用户身份，Depends并根据用户身份返回对应的权限，再比对权限是否在功能函数的要求权限范围内
def get_user_token(token: str | None = Cookie(None)):
    if token is None:
        raise HTTPException(status_code=401, detail="Not authenticated")
    return token


def get_user_permissions(token: str = Security(get_user_token)):
    if token == "Tai_admin":
        return "admin"
    elif token == "Tai_user":
        return "user"
    else:
        return "guest"


def check_user(security_scopes: SecurityScopes, user_permissions: str = Depends(get_user_permissions)):
    if user_permissions not in security_scopes.scopes:
        raise HTTPException(status_code=403, detail="Not enough permissions")


@app.get("/login", summary="模拟登录, 设置cookie")
async def login(response: Response, token: str = "Tai_admin"):
    response.set_cookie(key="token", value=token, expires=600)
    return {"msg": "登录成功"}


@app.post("/upload_file", summary="admin用户权限上传文件", dependencies=[Security(check_user, scopes=["admin"])])
async def upload_file(*, file: UploadFile, request: Request):
    # 保存文件
    with open(f"{file.filename}", "wb") as buffer:
        while content := await file.read(1024):
            buffer.write(content)
    # 返回文件信息
    # url = request.url_for("get_file", file_name=unique_name).path
    return {"url": file.filename}


@app.get("/echo", summary="request 对象")
async def get_request(req: Request, key1: str, key2: str):
    print(req)
    return {
        "base_url": req.base_url,
        "client": req.client,
        "cookies": req.cookies,
        # "body": await req.body(),
        "请求头部": req.headers,
        "method": req.method,
        "path_params": req.path_params,
        "query_params": req.query_params,
        "scope": {k: str(v) for k, v in req.scope.items()},
        "url": req.url,
        "协议名称": req.url.scheme,
        "主机名": req.url.hostname,
        "端口号": req.url.port,
        "路径": req.url.path,
        "查询字符串": req.url.query,
        "请求参数": req.query_params,
        "key1": key1,
        "key2": key2,
        "请求体": await req.body(),
    }
